package com.yongdui.process;

import com.yongdui.process.model.PeContext;
import com.yongdui.process.model.PeEdge;
import com.yongdui.process.model.PeNode;
import com.yongdui.process.model.PeProcess;
import com.yongdui.process.operator.IOperator;

import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 仅用于测试网络文章的工作流引擎，不可使用到实际业务当中
 */
public class ProcessEngine {
    private String xmlStr;

    //存储算子
    private Map<String, IOperator> type2Operator = new ConcurrentHashMap<>();
    private PeProcess peProcess = null;
    private PeContext peContext = null;

    //任务数据暂存
    public final BlockingQueue<PeNode> arrayBlockingQueue = new LinkedBlockingQueue();
    //任务调度线程
    public final Thread dispatchThread = new Thread(() -> {
        while (true) {
            try {
                PeNode node = arrayBlockingQueue.take();
                type2Operator.get(node.type).doTask(this, node, peContext);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    public ProcessEngine(String xmlStr) {
        this.xmlStr = xmlStr;
    }

    //算子注册到引擎中，便于引擎调用之
    public void registNodeProcessor(IOperator operator) {
        type2Operator.put(operator.getType(), operator);
    }

    public void start() {
        peProcess = new XmlPeProcessBuilder(xmlStr).build();
        peContext = new PeContext();

        dispatchThread.setDaemon(true);
        dispatchThread.start();

        executeNode(peProcess.start.onlyOneOut().to);
    }

    private void executeNode(PeNode node) {
        if (!node.type.equals("endEvent"))
            arrayBlockingQueue.add(node);
        else
            System.out.println("process finished!");
    }

    public void nodeFinished(PeEdge nextPeEdgeID) {
        executeNode(nextPeEdgeID.to);
    }
}
